{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "747e0e8d",
   "metadata": {},
   "source": [
    "# Quickstart with BentoML and XGBoost\n",
    "\n",
    "Link to source code: https://github.com/bentoml/BentoML/tree/main/examples/xgboost"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d4454bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "import xgboost\n",
    "import bentoml"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b66e31f7",
   "metadata": {},
   "source": [
    "### Train a classifier using the agaricus dataset:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eb526488",
   "metadata": {},
   "outputs": [],
   "source": [
    "# read in data\n",
    "dtrain = xgboost.DMatrix(\"data/agaricus.txt.train\")\n",
    "\n",
    "# specify parameters via map\n",
    "param = {\"max_depth\": 2, \"eta\": 1, \"objective\": \"binary:logistic\"}\n",
    "num_round = 2\n",
    "bst = xgboost.train(param, dtrain, num_round)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e94ed449",
   "metadata": {},
   "outputs": [],
   "source": [
    "bentoml.xgboost.save_model(\"agaricus\", bst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a876780",
   "metadata": {},
   "outputs": [],
   "source": [
    "!bentoml models list"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "672721c4",
   "metadata": {},
   "source": [
    "Test loading the model as a BentoML Runner instance:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "28ac794b",
   "metadata": {},
   "outputs": [],
   "source": [
    "test_runner = bentoml.xgboost.get(\"agaricus:latest\").to_runner()\n",
    "test_runner.init_local()\n",
    "\n",
    "# fmt: off\n",
    "test_runner.run([[0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0,\n",
    "                  0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,\n",
    "                  0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0,\n",
    "                  1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n",
    "                  1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1,\n",
    "                  0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,\n",
    "                  0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0,\n",
    "                  1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0,\n",
    "                  1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,\n",
    "                  0, 0, 0, 0, 0, 0, 1]])  # => array(0.01241208, dtype=float32)\n",
    "# fmt: on"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fa68254",
   "metadata": {},
   "source": [
    "### Create a BentoML Service for serving the model\n",
    "\n",
    "Note: using `%%writefile` here because `bentoml.Service` instance must be created in a separate `.py` file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "127aa3fd",
   "metadata": {},
   "outputs": [],
   "source": [
    "%%writefile agaricus.py\n",
    "import typing\n",
    "\n",
    "import bentoml\n",
    "import xgboost\n",
    "from bentoml.io import NumpyNdarray, File\n",
    "\n",
    "if typing.TYPE_CHECKING:\n",
    "    import numpy as np\n",
    "\n",
    "agaricus_runner = bentoml.xgboost.get(\"agaricus:latest\").to_runner()\n",
    "\n",
    "svc = bentoml.Service(\"agaricus\", runners=[agaricus_runner])\n",
    "\n",
    "@svc.api(input=NumpyNdarray(), output=NumpyNdarray())\n",
    "def classify(input_data: \"np.ndarray\") -> \"np.ndarray\":\n",
    "    return agaricus_runner.run(input_data)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "203beeed",
   "metadata": {},
   "source": [
    "Start a dev model server to test out the service defined above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7523b58f",
   "metadata": {},
   "outputs": [],
   "source": [
    "!bentoml serve agaricus.py:svc"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3974e4ce",
   "metadata": {},
   "source": [
    "Open a new browser tab and test out the API endpoint from the web UI."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f1a8bcc",
   "metadata": {},
   "source": [
    "### Build a Bento for distribution and deployment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ef11159",
   "metadata": {},
   "outputs": [],
   "source": [
    "!bentoml build"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47505e3c",
   "metadata": {},
   "source": [
    "Starting a dev server with the Bento build:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b7cab8b2",
   "metadata": {},
   "outputs": [],
   "source": [
    "!bentoml serve agaricus:latest"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4c159551",
   "metadata": {},
   "source": [
    "## Hooray, your model is ready for production now 🎉\n",
    "\n",
    "Bento is a standarized format for storing models alongside with all their API definitions, configuration, and environment settings. BentoML can start an REST API server serving a Bento, run a Bento as batch processing job on distributed dataset, or containerize all dependencies and models into a docker container image for easy production deployment."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81ed8b84",
   "metadata": {},
   "source": [
    "### Optional: create a docker image for the model server"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c215454",
   "metadata": {},
   "source": [
    "This will require docker to be installed and docker daemon to be running:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5047751c",
   "metadata": {},
   "outputs": [],
   "source": [
    "!bentoml containerize agaricus:latest"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b5bdf2a1",
   "metadata": {},
   "source": [
    "## What's next?\n",
    "\n",
    "* Learn more at http://docs.bentoml.com 📖\n",
    "* Join [BentoML Slack community](https://join.slack.com/t/bentoml/shared_invite/enQtNjcyMTY3MjE4NTgzLTU3ZDc1MWM5MzQxMWQxMzJiNTc1MTJmMzYzMTYwMjQ0OGEwNDFmZDkzYWQxNzgxYWNhNjAxZjk4MzI4OGY1Yjg) 👈\n",
    "* Follow us on [Twitter](https://twitter.com/bentomlai) 🐦\n",
    "* Contribute to [BentoML on GitHub](https://github.com/bentoml/BentoML) 💻"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65e092c7",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.10.5 64-bit ('3.10.5')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.5"
  },
  "vscode": {
   "interpreter": {
    "hash": "b6c37f2c42f5754f4e69d3366aab52a1fae3caec233d069fa3e31792c24a7a5a"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
